#include <iostream>

#include "io.h"

void write_uint(std::ostream &os, unsigned x)
{
    os.write(reinterpret_cast<const char *>(&x), 4);
}

unsigned read_uint(std::istream &is)
{
    unsigned r;
    is.read(reinterpret_cast<char *>(&r), 4);
    return r;
}

void write_string(std::ostream &os, const std::string &x)
{
    unsigned len = x.size();
    write_uint(os, len);
    os.write(x.c_str(), len);
}

std::string read_string(std::istream &is)
{
    unsigned len = read_uint(is);
    char *buf = new char[len + 1];
    is.read(buf, len);
    buf[len] = '\0';
    std::string r(buf);
    delete[] buf;
    return r;
}

void copy(std::istream &is, std::ostream &os)
{
    os << is.rdbuf();
}

void copy(std::istream &is, std::ostream &os, unsigned size)
{
    const unsigned buffer_size = 1024 * 1024 * 64;
    static char buffer[buffer_size];
    
    while(size)
    {
        if(size >= buffer_size)
        {
            is.read(buffer, buffer_size);
            os.write(buffer, buffer_size);
            size -= buffer_size;
        }
        else
        {
            is.read(buffer, size);
            os.write(buffer, size);
            break;
        }
    }
}

unsigned file_size(std::istream &is)
{
    std::streampos p = is.tellg();
    is.seekg(0, std::ios::end);
    std::streampos r = is.tellg();
    is.seekg(p);
    return r;
}
